﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using Atom.dao.Model;
using Atom.NetFrame;
using Atom.Tool;
using Protocol.dto;
using Protocol;

namespace Atom.Logic.Select
{
    public class SelectRoom : AbsMulitHandle, HandleInterface
    {
        public ConcurrentDictionary<int, SelectModel> teamOne = new ConcurrentDictionary<int, SelectModel>();
        public ConcurrentDictionary<int, SelectModel> teamTwo = new ConcurrentDictionary<int, SelectModel>();
        private int missionId;
        private int enterCount;

        public List<int> readList = new List<int>();
        public void Init(List<int> teamOne, List<int> teamTwo)
        {
            this.teamOne.Clear();
            this.teamTwo.Clear();
            enterCount = 0;
            foreach (int item in teamOne)
            {
                SelectModel model = new SelectModel();
                model.UserId = item;
                model.Name = GetUser(item).Name;
                model.Hero = -1;
                model.Enter = false;
                model.Ready = false;
                this.teamOne.TryAdd(item, model);
            }
            foreach (int item in teamTwo)
            {
                SelectModel model = new SelectModel();
                model.UserId = item;
                model.Name = GetUser(item).Name;
                model.Hero = -1;
                model.Enter = false;
                model.Ready = false;
                this.teamTwo.TryAdd(item, model);
            }
            //初始化完毕，开始定时任务，设定30秒后没有进入选择界面的时候，直接解散此次匹配
            missionId = ScheduleUtil.Instance.Schedule(delegate
            {
                //通知各个用户取消排位
                if (enterCount < this.teamOne.Count + this.teamTwo.Count)
                {
                    Destory();
                }
                else
                {
                    //30后，如果没有选择英雄，直接退出房间，回到主界面
                    missionId = ScheduleUtil.Instance.Schedule(delegate
                      {
                          bool isAllSelect = true;
                          foreach (int item in teamOne)
                          {
                              if (this.teamOne[item].Hero == -1)
                              {
                                  isAllSelect = false;
                                  break;
                              }
                          }
                          foreach (int item in teamTwo)
                          {
                              if (this.teamTwo[item].Hero == -1)
                              {
                                  isAllSelect = false;
                                  break;
                              }
                          }
                          //所有人都选择了英雄，只是有人没点准备
                          if (isAllSelect)
                          {
                              //通知所有用户跳转到战斗场景
                              StartFight();
                          }
                          else
                          {
                              //解散房间
                              Destory();
                          }
                      }, 300 * 1000);

                }
            }, 300 * 1000);
        }

        public void ClientClose(UserToken ut, string error)
        {
            //调用此方法，让此链接不再接受网络消息
            Level(ut);
            //通知房间所有人，房间解散，会主界面去
            Broadcast(SelectProtocol.DESTORY_BRO, null);
            //通知管理器 移除自身
            EventUtil.DestorySelect(GetArea());
        }

        public void ClientConnect(UserToken ut)
        {

        }

        public void MessageReceive(UserToken ut, SocketModel message)
        {
            switch (message.Command)
            {
                case SelectProtocol.ENTER_CREQ:
                    Enter(ut);
                    break;
                case SelectProtocol.READY_CREQ:
                    Ready(ut);
                    break;
                case SelectProtocol.SELECT_CREQ:
                    //Select(ut, message.GetMessage<int>());
                    break;
                case SelectProtocol.TALK_CREQ:
                    //Talk(ut, message.GetMessage<string>());
                    break;
            }

        }
        public override byte Gettype()
        {
            return GameProtocol.TYPE_SELECT;
        }

        private new void Enter(UserToken ut)
        {
            //改变进入状态
            int userId = GetUserID(ut);
            Console.Write("UserID:" + userId);
            if (teamOne.ContainsKey(userId))
            {
                teamOne[userId].Enter = true;
            }
            else if (teamTwo.ContainsKey(userId))
            {
                teamTwo[userId].Enter = true;
            }
            else
            {
                return;
            }

            if (base.Enter(ut))
            {
                enterCount++;
            }
            SelectRoomDTO dto = new SelectRoomDTO();
            dto.TeamOne = teamOne.Values.ToArray();
            dto.TeamTwo = teamTwo.Values.ToArray();
            dto.Area = GetArea();
            Console.Write(dto.TeamOne[0].Name + "  " + dto.TeamTwo[0].Name);
            //给新进来的玩家刷新所有的数据
            //Write(ut, SelectProtocol.ENTER_SRES, dto);
            //广播其他玩家，有人进来了
            //Broadcast(SelectProtocol.ENTER_EXBRO, userId, ut);
        }

        private void Ready(UserToken ut)
        {
            if (!base.IsEntered(ut)) return;
            int userId = GetUserID(ut);
            SelectModel model = null;
            if (teamOne.ContainsKey(userId))
            {
                model = teamOne[userId];
            }
            else if (teamTwo.ContainsKey(userId))
            {
                model = teamTwo[userId];
            }
            else
            {
                return;
            }
            //判断有没有英雄，没有英雄不让准备
            if (model.Hero == -1)
            {
                return;
            }
            else
            {
                model.Ready = true;
                readList.Add(userId);
                //Broadcast(SelectProtocol.READY_BRO, model);
                if (readList.Count >= teamOne.Count + teamTwo.Count)
                {
                    StartFight();
                }
            }


        }

        private void Select(UserToken ut, int heroId)
        {
            if (!base.IsEntered(ut)) return;
            UserMode user = GetUser(ut);
            if (!user.HeroList.Contains(heroId)) return;
            SelectModel model = null;
            if (teamOne.ContainsKey(user.ID))
            {
                foreach (SelectModel item in teamOne.Values)
                {
                    if (item.Hero == heroId) return;
                }
                model = teamOne[user.ID];
            }
            else if (teamTwo.ContainsKey(user.ID))
            {
                foreach (SelectModel item in teamTwo.Values)
                {
                    if (item.Hero == heroId) return;
                }
                model = teamTwo[user.ID];
            }
            else
            {
                return;
            }
            model.Hero = heroId;
            //Broadcast(SelectProtocol.SELECRT_BRO, model);

        }

        private void Talk(UserToken ut, string talkValue)
        {
            if (!base.IsEntered(ut)) return;
            UserMode user = GetUser(ut);
            //Broadcast(SelectProtocol.SELECRT_BRO, user.Name + ":" + talkValue);

        }
        private void Destory()
        {
            //通知房间所有人，房间解散
            Broadcast(SelectProtocol.DESTORY_BRO, null);
            //通知管理器 移除自身
            EventUtil.DestorySelect(GetArea());
            //如果还有计时器任务，解除它
            if (missionId != -1)
            {
                ScheduleUtil.Instance.RemoveMission(missionId);
                missionId = -1;
            }
            enterCount = 0;

        }

        //开始战斗
        private void StartFight()
        {
            //如果还有计时器任务，解除它
            if (missionId != -1)
            {
                ScheduleUtil.Instance.RemoveMission(missionId);
                missionId = -1;
            }
            //通知战斗模块，开始战斗
            Broadcast(SelectProtocol.FIGHT_BRO, null);
            //通知删除房间
            EventUtil.DestorySelect(GetArea());
            enterCount = 0;
        }

    }
}
